#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HOST "localhost"
#define USERNAME "root"
#define PASSWORD ""
#define DATABASE "tcmu"

#define BINARY_READ_FILE_PATH "/root/shunzi/abc.jpg"
#define BINARY_WRITE_FILE_PATH "/root/shunzi/abc2.jpg"

void printResult(MYSQL *mysqlPrint);
void finish_with_error(MYSQL *con);

int main()
{

    FILE *file = fopen(BINARY_READ_FILE_PATH, "rb");
    if (file == NULL)
    {
        printf("Cannot open the file!\n");
        return 0;
    }

    fseek(file, 0, SEEK_END);
    int flen = ftell(file);
    if (flen == -1)
    {

        perror("error occurred");
        int r = fclose(file);

        if (r == EOF)
        {
            printf("cannot close file handler\n");
        }

        exit(1);
    }

    fseek(file, 0, SEEK_SET);
    if (ferror(file))
    {

        printf("fseek() failed\n");
        int r = fclose(file);

        if (r == EOF)
        {
            printf("cannot close file handler\n");
        }

        exit(1);
    }

    char data[flen + 1];
    int size = fread(data, 1, flen, file);
    printf("Read file length : %d\n", flen);
    printf("Read size : %d\n", size);
    fclose(file);

    char chunk[2 * size + 1];
    MYSQL connection;
    mysql_init(&connection);
    mysql_real_connect(&connection, HOST, USERNAME, PASSWORD, DATABASE, 0, NULL, 0);

    // Test the connection with mysql host
    if (mysql_ping(&connection))
    {
        printf("Mysql connction is broken.\n");
        return 0;
    }
    mysql_real_escape_string(&connection, chunk, data, size);

    char *st = "INSERT INTO Images(Id, Data) VALUES(1, '%s')";
    size_t st_len = strlen(st);

    char query[st_len + 2 * size + 1];
    int len = snprintf(query, st_len + 2 * size + 1, st, chunk);
    int sql_execute_result = mysql_real_query(&connection, query, len);

    if (mysql_query(&connection, "SELECT Data FROM Images WHERE Id=1"))
    {
        finish_with_error(&connection);
    }

    MYSQL_RES *result = mysql_store_result(&connection);

    if (result == NULL)
    {
        finish_with_error(&connection);
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    // Get the length of query result.
    unsigned long *lengths = mysql_fetch_lengths(result);

    if (lengths == NULL)
    {
        finish_with_error(&connection);
    }

    FILE *fp = fopen(BINARY_WRITE_FILE_PATH, "wb");
    fwrite(row[0], lengths[0], 1, fp);

    if (ferror(fp))
    {
        printf("fwrite() failed\n");
        mysql_free_result(result);
        mysql_close(&connection);

        exit(1);
    }

    int r = fclose(fp);

    if (r == EOF)
    {
        fprintf(stderr, "cannot close file handler\n");
    }

    mysql_free_result(result);
    mysql_close(&connection);
    return 0;
}

void printResult(MYSQL *mysqlPrint)
{
    MYSQL_RES *result;
    int numFields = 0;
    int numRows = 0;
    MYSQL_FIELD *field;
    MYSQL_ROW row;
    int i = 0;
    result = mysql_store_result(mysqlPrint);
    numFields = mysql_num_fields(result);
    numRows = mysql_num_rows(result);
    while (field = mysql_fetch_field(result))
        printf("%s\t", field->name);
    printf("\n");
    if (result)
    {
        while (row = mysql_fetch_row(result))
        {
            for (i = 0; i < numFields; i++)
            {
                printf("%s\t", row[i]);
            }
            printf("\n");
        }
    }
    mysql_free_result(result);
}

void finish_with_error(MYSQL *con)
{
    printf("%s\n", mysql_error(con));
    mysql_close(con);
    exit(1);
}
